/*******************************************************************************
 *
 * File Name:          ForumActivity.java
 *
 * Created:            2006-10-29 8:50:42
 *
 * Original Author:    yu.peng
 *
 *------------------------------------------------------------------------------
 * MODIFICATION HISTORY
 *------------------------------------------------------------------------------
 * WHEN                WHO                 WHY
 * 2006-10-29 8:50:42 yu.peng             new
 *------------------------------------------------------------------------------
 *
 ******************************************************************************/
/*******************/
/* PACKAGE SECTION */
/*******************/
package org.njo.webapp.root.model.activity;

import org.njo.webapp.root.utility.SystemContext;
import org.njo.webapp.root.utility.ObjectNotExistsException;
import org.njo.webapp.root.model.dao.ForumDAO;
import org.njo.webapp.root.model.dao.Forum_access_logDAO;
import org.njo.webapp.root.model.dao.ForumboardDAO;
import org.njo.commons.lang.KeyUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.sql.SQLException;
import java.sql.Connection;
import java.util.List;
import java.util.Map;

/**
 * TODO:comment
 *
 * @author yu.peng
 * @version 0.01
 */
public class ForumActivity {

    /**
     * Log Object.
     */
    private static Log logger = LogFactory.getLog(ForumActivity.class);

    public void postSubject(String title,
                            String content,
                            String attachment,
                            int whenreplytomail,
                            String board,
                            String author,
                            String host) {
        Connection connection = null;
        ForumDAO forumDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);

            String id = KeyUtil.getUniqueKey();

            String previousid = forumDAO.getLastId(board);
            String nextid = forumDAO.getFirstIdOfTop(board);

            forumDAO.insert(id,
                            title,
                            content,
                            attachment,
                            whenreplytomail,
                            10,
                            null,
                            board,
                            previousid,
                            nextid,
                            null,
                            author,
                            host) ;

            // 更新前一条数据的 nextid
            forumDAO.updateNextId(previousid, id);
            // 更新后一条数据的 previousid
            forumDAO.updatePreviousId(nextid, id);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void replySubject(String title,
                            String content,
                            String attachment,
                            int whenreplytomail,
                            String replyid,
                            String board,
                            String author,
                            String host) {
        Connection connection = null;
        ForumDAO forumDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);

            String id = KeyUtil.getUniqueKey();

            String previousid = forumDAO.getLastId(board);
            String nextid = forumDAO.getFirstIdOfTop(board);
            String samesubjectpreviousid = forumDAO.getSameSubjectPreviousId(board, replyid);
            if (samesubjectpreviousid==null) {
                samesubjectpreviousid = replyid;
            }

            int flg = 10;
            forumDAO.insert(id,
                            title,
                            content,
                            attachment,
                            whenreplytomail,
                            flg,
                            replyid,
                            board,
                            previousid,
                            nextid,
                            samesubjectpreviousid,
                            author,
                            host) ;

            forumDAO.updateNextId(previousid, id);
            forumDAO.updatePreviousId(nextid, id);
            forumDAO.updateSameSubjectNextId(samesubjectpreviousid, id);

            connection.commit();
        } catch (SQLException ex) {
            ex.printStackTrace();
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public List listSubjects(String board, int start, int end) {
        Connection connection = null;
        ForumDAO forumDAO = null;
        Forum_access_logDAO forum_access_logDAO = null;
        List subjects = null;
        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);
            forum_access_logDAO = new Forum_access_logDAO(connection);

            subjects = forumDAO.selectSubjectsByBoard(board, start, end);
            for (int i = 0; i < subjects.size(); i++) {
                Map subject = (Map) subjects.get(i);
                String id = (String)subject.get("id");
                String accesscount = String.valueOf(forum_access_logDAO.getAccessCountByForumId(id));
                subject.put("accesscount", accesscount);
                String replycount = String.valueOf(forumDAO.replyCountById(id));
                subject.put("replycount", replycount);
            }

        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
        return subjects;
    }

    public int sizeOfBoard(String board) {
        Connection connection = null;
        ForumDAO forumDAO = null;
        int size = 0;
        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);

            size = forumDAO.sizeOfBoard(board);
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
        return size;
    }

    public List getBoards() {
        Connection connection = null;
        ForumboardDAO boardDAO = null;
        List boards = null;
        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            boardDAO = new ForumboardDAO(connection);
            boards = boardDAO.getBoardFolder();

            for (int i = 0; i < boards.size(); i++) {
                Map folder = (Map) boards.get(i);
                String id = (String)folder.get("id");
                List board = boardDAO.getBoards(id);
                folder.put("boards", board);
            }

        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
        return boards;
    }

    public Map getBoard(String boardId) throws ObjectNotExistsException {
        Connection connection = null;
        ForumboardDAO boardDAO = null;
        Map board = null;
        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            boardDAO = new ForumboardDAO(connection);
            board = boardDAO.getBoard(boardId);
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
        return board;
    }

    public Map loadSubject(String id, String user, String host) throws ObjectNotExistsException {
        Connection connection = null;
        ForumDAO forumDAO = null;
        Forum_access_logDAO accessLogDAO = null;
        Map subject = null;
        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);
            accessLogDAO = new Forum_access_logDAO(connection);
            subject = forumDAO.selectSubject(id);
            accessLogDAO.accessLog(id, user, host);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
        return subject;
    }

    public Map loadSubject(String id) throws ObjectNotExistsException {
        Connection connection = null;
        ForumDAO forumDAO = null;
        Map subject = null;
        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);
            subject = forumDAO.selectSubject(id);
            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
        return subject;
    }

    public void deleteSubject(String id) throws ObjectNotExistsException {
        Connection connection = null;
        ForumDAO forumDAO = null;
        Map subject = null;
        boolean isMainSubject = false;
        String previousid = null;
        String nextid = null;
        String spreviousid = null;
        String snextid = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);
            // 取得该文章的 详细信息
            subject = forumDAO.selectSubject(id);
            previousid = (String)subject.get("previousid");
            nextid = (String)subject.get("nextid");
            spreviousid = (String)subject.get("samesubjectpreviousid");
            snextid = (String)subject.get("samesubjectnextid");
            // 要删除的 文章是否是主 文章
            isMainSubject = subject.get("replyid") == null;

            if (isMainSubject) {
                List replys = forumDAO.getReplys(id);
                for (int i = 0; i < replys.size(); i++) {
                    Map reply = (Map) replys.get(i);
                    String subId = (String)reply.get("id");
                    String subpreviousid = (String)reply.get("previousid");
                    String subnextid = (String)reply.get("nextid");
                    String subspreviousid = (String)reply.get("samesubjectpreviousid");
                    String subsnextid = (String)reply.get("samesubjectnextid");
                    // 更新上一篇,下一篇链接
                    forumDAO.updateNextId(subpreviousid, subnextid);
                    forumDAO.updatePreviousId(subnextid, subpreviousid);
                    // 更新同主题上一篇,下一篇链接
                    forumDAO.updateSNextId(subspreviousid, subsnextid);
                    forumDAO.updateSPreviousId(subsnextid, subspreviousid);
                    forumDAO.deleteSubject(subId);
                }
                // 更新上一篇,下一篇链接
                forumDAO.updateNextId(previousid, nextid);
                forumDAO.updatePreviousId(nextid, previousid);

                forumDAO.deleteSubject(id);
            } else {
                // 更新上一篇,下一篇链接
                forumDAO.updateNextId(previousid, nextid);
                forumDAO.updatePreviousId(nextid, previousid);
                // 更新同主题上一篇,下一篇链接
                forumDAO.updateSNextId(spreviousid, snextid);
                forumDAO.updateSPreviousId(snextid, spreviousid);

                forumDAO.deleteSubject(id);
            }

            connection.commit();
        } catch (SQLException ex) {
            ex.printStackTrace();
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void takeTop(String id) {
        Connection connection = null;
        ForumDAO forumDAO = null;
        Map subject = null;
        boolean isMainSubject = false;
        String previousid = null;
        String nextid = null;
        // String spreviousid = null;
        // String snextid = null;
        String board = null;

        String topId = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);
            // 取得该文章的 详细信息
            subject = forumDAO.selectSubject(id);
            // 文章是否是主 文章
            isMainSubject = subject.get("replyid") == null;

            if (isMainSubject) {
                topId = id;
            } else {
                topId = (String)subject.get("replyid");
                // 取得该文章的 详细信息
                subject = forumDAO.selectSubject(topId);
            }

            board = (String)subject.get("board");
            previousid = (String)subject.get("previousid");
            nextid = (String)subject.get("nextid");

            // 更新上一篇,下一篇链接
            forumDAO.updateNextId(previousid, nextid);
            forumDAO.updatePreviousId(nextid, previousid);

            String lastid = forumDAO.getLastIdWithTop(board);
            forumDAO.updateNextId(lastid, topId);

            forumDAO.takeTop(topId, lastid, null);
            connection.commit();
        } catch (SQLException ex) {
            ex.printStackTrace();
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void unTop(String id) {
        Connection connection = null;
        ForumDAO forumDAO = null;
        Map subject = null;
        String board = null;
        String previousid = null;
        String nextid = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            forumDAO = new ForumDAO(connection);

            // 取得该文章的 详细信息
            subject = forumDAO.selectSubject(id);
            // 要删除的 文章是否是主 文章
            String flg = (String)subject.get("flg");
            boolean isTop = ("100".equals(flg));
            if (!isTop) {
                return ;
            }
            board = (String)subject.get("board");
            previousid = (String)subject.get("previousid");
            nextid = (String)subject.get("nextid");

            // 更新上一篇,下一篇链接
            forumDAO.updateNextId(previousid, nextid);
            forumDAO.updatePreviousId(nextid, previousid);

            previousid = forumDAO.getLastId(board);
            nextid = forumDAO.getFirstIdOfTop(board);

            forumDAO.updateNextId(previousid, id);
            forumDAO.updatePreviousId(nextid, id);

            forumDAO.unTop(id, previousid, nextid);

            connection.commit();
        } catch (SQLException ex) {
            ex.printStackTrace();
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

}
